home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / dev / c / TinyGL.lha / tinygl / examples / gears.c next >
Encoding:
C/C++ Source or Header  |  2002-08-28  |  7.7 KB  |  298 lines

  1. /* gears.c */
  2.  
  3. /*
  4.  * 3-D gear wheels.  This program is in the public domain.
  5.  *
  6.  * Brian Paul
  7.  */
  8.  
  9.  
  10. #include <math.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14.  
  15. #include <GL/glut.h>
  16.  
  17. #ifndef M_PI
  18. #  define M_PI 3.14159265
  19. #endif
  20.  
  21.  
  22. /*
  23.  * Draw a gear wheel.  You'll probably want to call this function when
  24.  * building a display list since we do a lot of trig here.
  25.  *
  26.  * Input:  inner_radius - radius of hole at center
  27.  *         outer_radius - radius at center of teeth
  28.  *         width - width of gear
  29.  *         teeth - number of teeth
  30.  *         tooth_depth - depth of tooth
  31.  */
  32. static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
  33.           GLint teeth, GLfloat tooth_depth )
  34. {
  35.    GLint i;
  36.    GLfloat r0, r1, r2;
  37.    GLfloat angle, da;
  38.    GLfloat u, v, len;
  39.  
  40.    r0 = inner_radius;
  41.    r1 = outer_radius - tooth_depth/2.0;
  42.    r2 = outer_radius + tooth_depth/2.0;
  43.  
  44.    da = 2.0*M_PI / teeth / 4.0;
  45.  
  46.    glShadeModel( GL_FLAT );
  47.  
  48.    glNormal3f( 0.0, 0.0, 1.0 );
  49.  
  50.    /* draw front face */
  51.    glBegin( GL_QUAD_STRIP );
  52.    for (i=0;i<=teeth;i++) {
  53.       angle = i * 2.0*M_PI / teeth;
  54.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  55.       glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
  56.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  57.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
  58.    }
  59.    glEnd();
  60.  
  61.    /* draw front sides of teeth */
  62.    glBegin( GL_QUADS );
  63.    da = 2.0*M_PI / teeth / 4.0;
  64.    for (i=0;i<teeth;i++) {
  65.       angle = i * 2.0*M_PI / teeth;
  66.  
  67.       glVertex3f( r1*cos(angle),      r1*sin(angle),      width*0.5 );
  68.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   width*0.5 );
  69.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
  70.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
  71.    }
  72.    glEnd();
  73.  
  74.  
  75.    glNormal3f( 0.0, 0.0, -1.0 );
  76.  
  77.    /* draw back face */
  78.    glBegin( GL_QUAD_STRIP );
  79.    for (i=0;i<=teeth;i++) {
  80.       angle = i * 2.0*M_PI / teeth;
  81.       glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
  82.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  83.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  84.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  85.    }
  86.    glEnd();
  87.  
  88.    /* draw back sides of teeth */
  89.    glBegin( GL_QUADS );
  90.    da = 2.0*M_PI / teeth / 4.0;
  91.    for (i=0;i<teeth;i++) {
  92.       angle = i * 2.0*M_PI / teeth;
  93.  
  94.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  95.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
  96.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
  97.       glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
  98.    }
  99.    glEnd();
  100.  
  101.  
  102.    /* draw outward faces of teeth */
  103.    glBegin( GL_QUAD_STRIP );
  104.    for (i=0;i<teeth;i++) {
  105.       angle = i * 2.0*M_PI / teeth;
  106.  
  107.       glVertex3f( r1*cos(angle),      r1*sin(angle),       width*0.5 );
  108.       glVertex3f( r1*cos(angle),      r1*sin(angle),      -width*0.5 );
  109.       u = r2*cos(angle+da) - r1*cos(angle);
  110.       v = r2*sin(angle+da) - r1*sin(angle);
  111.       len = sqrt( u*u + v*v );
  112.       u /= len;
  113.       v /= len;
  114.       glNormal3f( v, -u, 0.0 );
  115.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),    width*0.5 );
  116.       glVertex3f( r2*cos(angle+da),   r2*sin(angle+da),   -width*0.5 );
  117.       glNormal3f( cos(angle), sin(angle), 0.0 );
  118.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da),  width*0.5 );
  119.       glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
  120.       u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
  121.       v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
  122.       glNormal3f( v, -u, 0.0 );
  123.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da),  width*0.5 );
  124.       glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
  125.       glNormal3f( cos(angle), sin(angle), 0.0 );
  126.    }
  127.  
  128.    glVertex3f( r1*cos(0), r1*sin(0), width*0.5 );
  129.    glVertex3f( r1*cos(0), r1*sin(0), -width*0.5 );
  130.  
  131.    glEnd();
  132.  
  133.  
  134.    glShadeModel( GL_SMOOTH );
  135.  
  136.    /* draw inside radius cylinder */
  137.    glBegin( GL_QUAD_STRIP );
  138.    for (i=0;i<=teeth;i++) {
  139.       angle = i * 2.0*M_PI / teeth;
  140.       glNormal3f( -cos(angle), -sin(angle), 0.0 );
  141.       glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
  142.       glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
  143.    }
  144.    glEnd();
  145.       
  146. }
  147.  
  148.  
  149. static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0;
  150. static GLint gear1, gear2, gear3;
  151. static GLfloat angle = 0.0;
  152.  
  153. static GLuint limit;
  154. static GLuint count = 1;
  155.  
  156.  
  157. void draw( void )
  158. {
  159.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  160.  
  161.    glPushMatrix();
  162.    glRotatef( view_rotx, 1.0, 0.0, 0.0 );
  163.    glRotatef( view_roty, 0.0, 1.0, 0.0 );
  164.    glRotatef( view_rotz, 0.0, 0.0, 1.0 );
  165.  
  166.    glPushMatrix();
  167.    glTranslatef( -3.0, -2.0, 0.0 );
  168.    glRotatef( angle, 0.0, 0.0, 1.0 );
  169.    glCallList(gear1);
  170.    glPopMatrix();
  171.  
  172.    glPushMatrix();
  173.    glTranslatef( 3.1, -2.0, 0.0 );
  174.    glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
  175.    glCallList(gear2);
  176.    glPopMatrix();
  177.  
  178.    glPushMatrix();
  179.    glTranslatef( -3.1, 4.2, 0.0 );
  180.    glRotatef( -2.0*angle-25.0, 0.0, 0.0, 1.0 );
  181.    glCallList(gear3);
  182.    glPopMatrix();
  183.  
  184.    glPopMatrix();
  185.  
  186.      glutSwapBuffers();
  187.  
  188.    count++;
  189.    if (count==limit) {
  190.        exit(0);
  191.    }
  192. }
  193.  
  194.  
  195. /*
  196. // When idle will work, uncomment this function and delete the
  197. // glutPostDisplay() call in the keyboard() function
  198. void idle( void )
  199. {
  200.    angle += 2.0;
  201.    draw();
  202. }
  203. */
  204.  
  205.  
  206. /* change view angle, exit upon ESC */
  207. void keyboard(unsigned char key, int x, int y)
  208. {
  209.     switch (key) {
  210.         case 76: // KEY_UP:
  211.             view_rotx += 5.0;
  212.             break;
  213.         case 77: // KEY_DOWN:
  214.             view_rotx -= 5.0;
  215.             break;
  216.         case 79: // KEY_LEFT:
  217.             view_roty += 5.0;
  218.             break;
  219.         case 78: // KEY_RIGHT:
  220.             view_roty -= 5.0;
  221.             break;
  222.         case 97: // 'z'
  223.             view_rotz += 5.0;
  224.             break;
  225.         case 122: // 'a':
  226.             view_rotz -= 5.0;
  227.             break;
  228.     }
  229.     glutPostRedisplay();
  230. }
  231.  
  232. /* new window size or exposure */
  233. void reshape( int width, int height )
  234. {
  235.    GLfloat  h = (GLfloat) height / (GLfloat) width;
  236.  
  237.    glViewport(0, 0, (GLint)width, (GLint)height);
  238.    glMatrixMode(GL_PROJECTION);
  239.    glLoadIdentity();
  240.    glFrustum( -1.0, 1.0, -h, h, 5.0, 60.0 );
  241.    glMatrixMode(GL_MODELVIEW);
  242.    glLoadIdentity();
  243.    glTranslatef( 0.0, 0.0, -40.0 );
  244.    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  245. }
  246.  
  247.  
  248. void init( void )
  249. {
  250.    static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0 };
  251.    static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0 };
  252.    static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0 };
  253.    static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0 };
  254.  
  255.    glLightfv( GL_LIGHT0, GL_POSITION, pos );
  256.    glEnable( GL_CULL_FACE );
  257.    glEnable( GL_LIGHTING );
  258.    glEnable( GL_LIGHT0 );
  259.    glEnable( GL_DEPTH_TEST );
  260.  
  261.    /* make the gears */
  262.    gear1 = glGenLists(1);
  263.    glNewList(gear1, GL_COMPILE);
  264.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red );
  265.    gear( 1.0, 4.0, 1.0, 20, 0.7 );
  266.    glEndList();
  267.  
  268.    gear2 = glGenLists(1);
  269.    glNewList(gear2, GL_COMPILE);
  270.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  271.    gear( 0.5, 2.0, 2.0, 10, 0.7 );
  272.    glEndList();
  273.  
  274.    gear3 = glGenLists(1);
  275.    glNewList(gear3, GL_COMPILE);
  276.    glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue );
  277.    gear( 1.3, 2.0, 0.5, 10, 0.7 );
  278.    glEndList();
  279.  
  280.    glEnable( GL_NORMALIZE );
  281. }
  282.  
  283. int main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
  284. {
  285.   glutInit            ( &argc, argv ); // Erm Just Write It =)
  286.   glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE ); // Display Mode
  287.     glutInitWindowSize  ( 320, 256 ); // If glutFullScreen wasn't called this is the window size
  288.   glutCreateWindow    ( "NeHe's OpenGL Framework" ); // Window Title (argv[0] for current directory as title)
  289.     init();
  290.     glutDisplayFunc     ( draw );  // Matching Earlier Functions To Their Counterparts
  291.   glutReshapeFunc     ( reshape );
  292.     glutKeyboardFunc    ( keyboard );
  293.   glutMainLoop        ( );          // Initialize The Main Loop
  294.  
  295.     return 0;
  296. }
  297.  
  298.